package seata.order.service.service.impl;

import com.xfanonymous.cloud.api.AccountFeignApi;
import com.xfanonymous.cloud.api.StorageFeignApi;
import seata.order.service.entities.Order;
import seata.order.service.mapper.OrderMapper;
import seata.order.service.service.OrderService;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

/**
 * @auther xfanonymous
 * @create 2024-01-06 15:40
 *
 * Service实现类
 * 1. 注解 @Service、酸辣粉 @Slf4j
 * 2. 通过mapper接口执行数据库操作 @Resource
 * 3. 分别通过Feign接口调用库存、账户微服务
 * 4. 实现Service接口的业务方法 implements Service
 * 5. 通过Seata上下文 RootContext.getXID(); 获取全局事务ID，方便定位
 * 6. 通过Feign调用服务扣减库存、扣减账户余额
 * 7. 修改订单状态，表示下订单完整流程结束
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService
{
    @Resource
    private OrderMapper orderMapper;

    @Resource//订单微服务通过OpenFeign去调用库存微服务
    private StorageFeignApi storageFeignApi;

    @Resource//订单微服务通过OpenFeign去调用账户微服务
    private AccountFeignApi accountFeignApi;

    @Override
    @GlobalTransactional(name = "zzyy-create-order",rollbackFor = Exception.class) //AT
    public void create(Order order)
    {
        // 获取全局事务id方便定位，重要
        String xid = RootContext.getXID();

        //1 新建订单
        log.info("---------------开始新建订单: "+"\t"+"xid: "+xid);
        // 创建订单时，订单默认初始状态是零
        order.setStatus(0);
        // 通过Mapper接口将订单插入数据库
        int result = orderMapper.insertSelective(order);

        // 插入订单成功后获得插入mysql的实体对象
        Order orderFromDB = null;
        if(result > 0)
        {
            // 插入且能查出，说明插入数据成功。从mysql里面查出刚插入的记录
            orderFromDB = orderMapper.selectOne(order);
            log.info("-----> 新建订单成功,orderFromDB info: "+orderFromDB);
            System.out.println();

            //2 扣减库存
            log.info("-------> 订单微服务开始调用Storage库存，做扣减count");
            storageFeignApi.decrease(orderFromDB.getProductId(),orderFromDB.getCount());
            log.info("-------> 订单微服务结束调用Storage库存，做扣减完成");
            System.out.println();

            //3 扣减账户余额
            log.info("-------> 订单微服务开始调用Account账号，做扣减money");
            accountFeignApi.decrease(orderFromDB.getUserId(),orderFromDB.getMoney());
            log.info("-------> 订单微服务结束调用Account账号，做扣减完成");
            System.out.println();

            //4 修改订单状态
            //将订单状态从零修改为1，表示已经完成
            log.info("-------> 修改订单状态");
            orderFromDB.setStatus(1);

            //5 将更新后的数据刷新到数据库，Example是MyBatis查询条件
            Example whereCondition = new Example(Order.class);
            Example.Criteria criteria = whereCondition.createCriteria();
            // 相当于，where userId = id
            criteria.andEqualTo("userId", orderFromDB.getUserId());
            criteria.andEqualTo("status", 0);
            // 按照whereCondition条件更新订单数据orderFromDB，并获取结果
            int updateResult = orderMapper.updateByExampleSelective(orderFromDB, whereCondition);
            log.info("-------> 修改订单状态完成"+"\t"+updateResult);
            log.info("-------> orderFromDB info: "+orderFromDB);
        }
        System.out.println();
        log.info("---------------结束新建订单: "+"\t"+"xid: "+xid);
    }
}
